home *** CD-ROM | disk | FTP | other *** search
- (***************************************************************************
-
- $RCSfile: StdIO.mod $
- Description: Simple formatted I/O using the standard input and output
- handles.
-
- Created by: fjc (Frank Copeland)
- $Revision: 1.15 $
- $Author: fjc $
- $Date: 1995/06/29 19:06:56 $
-
- Copyright © 1994, Frank Copeland.
- This file is part of the Oberon-A Library.
- See Oberon-A.doc for conditions of use and distribution.
-
- ***************************************************************************)
-
- <* STANDARD- *>
-
- MODULE StdIO;
-
- IMPORT SYS := SYSTEM, e := Exec, d := Dos, du := DosUtil, Reals, WbConsole;
-
- CONST
- maxD = 9;
-
- (*------------------------------------*)
- PROCEDURE Write* (ch : CHAR);
-
- BEGIN (* Write *)
- du.HaltIfBreak ({d.ctrlC});
- SYS.PUTREG (0, d.Write (d.Output(), ch, 1))
- END Write;
-
- (*------------------------------------*)
- PROCEDURE WriteLn*;
-
- BEGIN (* WriteLn *)
- Write (0AX)
- END WriteLn;
-
- (*------------------------------------*)
- PROCEDURE WriteStr* (s : ARRAY OF CHAR);
-
- <*$CopyArrays-*>
- BEGIN (* WriteStr *)
- du.HaltIfBreak ({d.ctrlC});
- SYS.PUTREG (0, d.Write (d.Output (), s, SYS.STRLEN (s)))
- END WriteStr;
-
- (*------------------------------------*)
- PROCEDURE* PutCh ();
-
- <*$EntryExitCode-*>
- BEGIN (* PutCh *)
- SYS.INLINE (16C0H, (* MOVE.B D0,(A3)+ *)
- 4E75H) (* RTS *)
- END PutCh;
-
- (*------------------------------------*)
- PROCEDURE WriteInt* (i : LONGINT);
-
- VAR
- str : ARRAY 256 OF CHAR;
-
- BEGIN (* WriteInt *)
- e.OldRawDoFmtL ("%ld", i, PutCh, SYS.ADR (str));
- WriteStr (str)
- END WriteInt;
-
- (*------------------------------------*)
- PROCEDURE WriteHex* (i : LONGINT);
-
- VAR
- str : ARRAY 256 OF CHAR;
-
- BEGIN (* WriteHex *)
- e.OldRawDoFmtL ("%lx", i, PutCh, SYS.ADR (str));
- WriteStr (str)
- END WriteHex;
-
- (*
- * The following WriteReal* and WriteLongReal* procedures have been pinched
- * from Module Texts and have been somewhat modified from the original code
- * described in "Project Oberon".
- *)
-
- (*------------------------------------*)
- PROCEDURE WriteReal * ( x : REAL; n : INTEGER );
-
- VAR e : INTEGER; x0 : REAL; d : ARRAY maxD OF CHAR;
-
- BEGIN (* WriteReal *)
- e := Reals.Expo (x);
- IF e = 0 THEN
- WriteStr ("0");
- REPEAT Write (" "); DEC (n) UNTIL n <= 3
- ELSIF e = 255 THEN
- WriteStr ("NaN");
- WHILE n > 4 DO Write (" "); DEC (n) END
- ELSE
- IF n <= 9 THEN n := 3 ELSE DEC (n, 6) END;
- REPEAT Write (" "); DEC (n) UNTIL n <= 8;
- (* there are 2 < n <= 8 digits to be written *)
- IF x < 0.0 THEN Write ("-"); x := -x ELSE Write (" ") END;
- e := (e - 127) * 77 DIV 256;
- IF e >= 0 THEN x := x / Reals.Ten (e) ELSE x := Reals.Ten (-e) * x END;
- IF x >= 10.0 THEN x := 0.1 * x; INC (e) END;
- x0 := Reals.Ten (n - 1); x := x0 * x + 0.5;
- IF x >= 10.0 * x0 THEN x := x * 0.1; INC (e) END;
- Reals.Convert (x, n, d);
- DEC (n); Write (d [n]); Write (".");
- REPEAT DEC (n); Write (d [n]) UNTIL n = 0;
- Write ("E");
- IF e < 0 THEN Write ("-"); e := -e ELSE Write ("+") END;
- Write (CHR (e DIV 10 + 30H)); Write (CHR (e MOD 10 + 30H))
- END
- END WriteReal;
-
- (*------------------------------------*)
- PROCEDURE WriteRealFix * ( x : REAL; n, k : INTEGER );
-
- VAR e, i : INTEGER; sign : CHAR; x0 : REAL; d : ARRAY maxD OF CHAR;
-
- (*------------------------------------*)
- PROCEDURE seq ( ch : CHAR; n : LONGINT );
-
- BEGIN (* seq *)
- WHILE n > 0 DO Write (ch); DEC (n) END
- END seq;
-
- (*------------------------------------*)
- PROCEDURE dig (n : INTEGER);
-
- BEGIN (* dig *)
- WHILE n > 0 DO
- DEC (i); Write (d [i]); DEC (n)
- END;
- END dig;
-
- BEGIN (* WriteRealFix *)
- e := Reals.Expo (x);
- IF k < 0 THEN k := 0 END;
- IF e = 0 THEN
- seq (" ", n - k - 2); Write ("0"); seq (" ", k + 1)
- ELSIF e = 255 THEN
- WriteStr ("NaN"); seq (" ", n - 4)
- ELSE
- e := (e - 127) * 77 DIV 256;
- IF x < 0.0 THEN sign := "-"; x := -x ELSE sign := " " END;
- IF e >= 0 THEN (* x >= 1.0, 77/256 = log 2 *) x := x / Reals.Ten (e)
- ELSE (* x < 1.0 *) x := Reals.Ten (-e) * x
- END;
- IF x >= 10.0 THEN x := 0.1 * x; INC (e) END;
- (* 1 <= x < 10 *)
- IF k + e >= maxD - 1 THEN k := maxD - 1 - e
- ELSIF k + e < 0 THEN k := -e; x := 0.0
- END;
- x0 := Reals.Ten (k + e); x := x0 * x + 0.5;
- IF x >= 10.0 * x0 THEN INC (e) END;
- (* e = no. of digits before decimal point *)
- INC (e); i := k + e; Reals.Convert (x, i, d);
- IF e > 0 THEN
- seq (" ", n - e - k - 2); Write (sign); dig (e); Write (".");
- dig (k)
- ELSE
- seq (" ", n - k - 3); Write (sign); Write ("0"); Write (".");
- seq ("0", -e); dig (k + e)
- END
- END
- END WriteRealFix;
-
- (*------------------------------------*)
- PROCEDURE WriteRealHex * ( x : REAL );
-
- VAR d : ARRAY 9 OF CHAR;
-
- BEGIN (* WriteRealHex *)
- Reals.ConvertH (x, d); d [8] := 0X; WriteStr (d)
- END WriteRealHex;
-
- (*------------------------------------*)
- PROCEDURE WriteLongReal * ( x : LONGREAL; n : INTEGER );
-
- BEGIN (* WriteLongReal *)
- (*
- * In this implementation, LONGREAL and REAL types are the same, so this
- * procedure is implemented as a call to WriteReal ().
- *)
- WriteReal (SHORT (x), n)
- END WriteLongReal;
-
- (*------------------------------------*)
- PROCEDURE WriteLongRealHex * ( x : LONGREAL );
-
- BEGIN (* WriteLongRealHex *)
- (*
- * In this implementation, LONGREAL and REAL types are the same, so this
- * procedure is implemented as a call to WriteRealHex ().
- *)
- WriteRealHex (SHORT (x))
- END WriteLongRealHex;
-
- (*------------------------------------*)
- PROCEDURE WriteF* (
- fs : ARRAY OF CHAR; VAR f : ARRAY OF SYS.LONGWORD);
-
- VAR
- str : ARRAY 256 OF CHAR;
-
- <*$CopyArrays-*>
- BEGIN (* WriteF *)
- e.OldRawDoFmtL (fs, f, PutCh, SYS.ADR (str));
- WriteStr (str)
- END WriteF;
-
- (*------------------------------------*)
- PROCEDURE WriteF1*
- ( fs : ARRAY OF CHAR;
- param1 : SYS.LONGWORD);
-
- VAR str : ARRAY 256 OF CHAR;
-
- <*$CopyArrays-*>
- BEGIN (* WriteF1 *)
- e.OldRawDoFmtL (fs, param1, PutCh, SYS.ADR (str));
- WriteStr (str)
- END WriteF1;
-
- (*------------------------------------*)
- PROCEDURE WriteF2* (
- fs : ARRAY OF CHAR; param1, param2 : SYS.LONGWORD);
-
- VAR str : ARRAY 256 OF CHAR; t : SYS.LONGWORD;
-
- <*$CopyArrays-*>
- BEGIN (* WriteF2 *)
- t := param1; param1 := param2; param2 := t;
- e.OldRawDoFmtL (fs, param2, PutCh, SYS.ADR (str));
- WriteStr (str)
- END WriteF2;
-
- (*------------------------------------*)
- PROCEDURE WriteF3* (
- fs : ARRAY OF CHAR; param1, param2, param3 : SYS.LONGWORD);
-
- VAR str : ARRAY 256 OF CHAR; t : SYS.LONGWORD;
-
- <*$CopyArrays-*>
- BEGIN (* WriteF3 *)
- t := param1; param1 := param3; param3 := t;
- e.OldRawDoFmtL (fs, param3, PutCh, SYS.ADR (str));
- WriteStr (str)
- END WriteF3;
-
- (*------------------------------------*)
- PROCEDURE Read* (VAR ch : CHAR);
-
- BEGIN (* Read *)
- du.HaltIfBreak ({d.ctrlC});
- IF d.Read (d.Input (), ch, 1) < 1 THEN ch := 0X END;
- END Read;
-
- (*------------------------------------*)
- PROCEDURE ReadStr* (VAR str : ARRAY OF CHAR);
-
- VAR ch : CHAR; index, limit : INTEGER;
-
- BEGIN (* ReadStr *)
- (* Skip white space *)
- REPEAT Read (ch) UNTIL (ch # " ") & (ch # 09X);
- (* Read until control char *)
- index := 0; limit := SHORT (LEN (str));
- WHILE (ch >= " ") & (index < limit) DO
- str [index] := ch; INC (index); Read (ch);
- END; (* WHILE *)
- str [index] := 0X;
- (* Skip rest of line if any *)
- WHILE ch >= " " DO Read (ch) END;
- END ReadStr;
-
- END StdIO.
-